package cz.muni.fi.pa165.musiclibrary.impl.database.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.hibernate.annotations.Type;
import org.joda.time.Duration;


/**
 *
 * @author Martin Szabo
 * 2012-10-12T19:20:04+0200
 */
@Entity
@Table(name="song")
public class Song implements ISong {
    
    /**
     * Identifier of this song.
     */
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    @Column(name="id_song")
    private Long idSong;
    
    /**
     * Artist of this song.
     */
    @ManyToOne
    @JoinColumn(name="id_artist")
    private Artist artist;
    
    /**
     * Genre of this song.
     */
    @ManyToOne
    @JoinColumn(name="id_genre")
    private Genre genre;
    
    /**
     * Album of this song.
     */
    @ManyToOne
    @JoinColumn(name="id_album")
    private Album album;
    
    /**
     * Title of this song.
     */
    private String title;
    
    /**
     * Bitrate of this song.
     */
    private Integer bitrate;
    
    /**
     * Duration of this song.
     */
    @Column(name="length_song")
    @Type(type="org.jadira.usertype.dateandtime.joda.PersistentDurationAsString")
    private Duration lengthSong;
    
    /**
     * Position on album of this song
     */
    @Column(name="track_number")
    private Integer trackNumber;
    
    /**
     * Description or comment for this song
     */
    private String comment;

    public Song(Long idSong, Artist artist, Genre genre, String title, Integer bitrate) {
        this.idSong = idSong;
        this.artist = artist;
        this.genre = genre;
        this.title = title;
        this.bitrate = bitrate;
    }
    
    public Song(){
        
    }

    @Override
    public Long getIdSong() {
        return idSong;
    }
    
    @Override
    public void setIdSong(Long idSong) {
        this.idSong = idSong;
    }
    @Override
    public IArtist getArtist() {
        return artist;
    }
    
    @Override
    public void setArtist(IArtist artist) {
        Validate.isTrue(artist instanceof Artist, "Artist instance is of invalid class.");
        this.artist = (Artist) artist;
    }
    
    @Override
    public IGenre getGenre() {
        return genre;
    }
    
    @Override
    public void setGenre(IGenre genre) {
        Validate.isTrue(genre instanceof Genre, "Genre instance is of invalid class.");
        this.genre = (Genre) genre;
    }
        
    @Override
    public IAlbum getAlbum() {
        return album;
    }
    
    @Override
    public void setAlbum(IAlbum album) {
        Validate.isTrue(album instanceof Album, "Album instance is of invalid class.");
        this.album = (Album) album;
    }
    
    @Override
    public String getTitle() {
        return title;
    }
    
    @Override
    public void setTitle(String title) {
        this.title = title;
    }
    
    @Override
    public Integer getBitrate() {
        return bitrate;
    }
    
    @Override
    public void setBitrate(Integer bitrate) {
        this.bitrate = bitrate;
    }
    
    @Override
    public Duration getLength() {
        return lengthSong;
    }
    
    @Override
    public void setLength(Duration length) {
        this.lengthSong = length;
    }
    
    @Override
    public Integer getTrackNumber() {
        return trackNumber;
    }
    
    @Override
    public void setTrackNumber(Integer trackNumber) {
        this.trackNumber = trackNumber;
    }
    
    @Override
    public String getComment() {
        return comment;
    }
    
    @Override
    public void setComment(String comment) {
        this.comment = comment;
    }
    
    @Override
    public boolean equals(final Object obj){
        if (obj instanceof ISong){
            return ( ((ISong)obj).getIdSong() == this.idSong  );
        } else {
            return false;
        }
    }
    
    @Override
    public int hashCode(){
        return (int) (31* this.idSong) % 1000;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
    }
    
}
